package main

import (
	"bufio"
	"context"
	"fmt"
	"m3u8-gui/dl"
	"m3u8-gui/tool"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
)

// App struct
type App struct {
	ctx context.Context
}

type Res struct {
	Data string
	Code int
}

// NewApp creates a new App application struct
func NewApp() *App {
	return &App{}
}

// startup is called when the app starts. The context is saved
// so we can call the runtime methods
func (a *App) startup(ctx context.Context) {
	a.ctx = ctx
}

// Greet returns a greeting for the given name
func (a *App) Greet(name string) string {
	return fmt.Sprintf("Hello %s, It's show time!", name)
}

// 文件下载
func (a *App) Download(fileUrl, name, folder string) Res {
	fmt.Printf("url=%s, name=%s, folder=%s \n", fileUrl, name, folder)
	res, err := download0(fileUrl, name, folder)
	if err != nil {
		return Res{Data: err.Error(), Code: 500}
	}
	return res
}

// 查询进度
func (a *App) Jd(id, fileUrl string) *tool.Progress {
	if len(id) == 0 {
		id = fileUrl
	}
	return tool.GetProgress(id)
}

// 合并ts文件
func (a *App) MergeTs(fileUrl, name, folder string) string {
	if len(fileUrl) == 0 {
		return "下载url为空"
	}
	if !tool.IsValidURL(fileUrl) {
		return "url非法"
	}
	fileUrl = strings.TrimSpace(fileUrl)
	id := tool.GetMd5(fileUrl)
	if len(name) == 0 && len(id) > 0 {
		name = id
	}
	mvName := path.Join(folder, name+".ts")
	outMv, _ := os.Create(mvName)
	defer outMv.Close()
	writer := bufio.NewWriter(outMv)
	var fileNum []int
	err := filepath.Walk(path.Join(folder, id), func(path string, f os.FileInfo, err error) error {
		if f == nil {
			return err
		}
		if f.IsDir() || filepath.Ext(path) != ".ts" {
			return nil
		}
		tmpName := f.Name()
		num, _ := strconv.Atoi(tmpName[0 : len(tmpName)-3])
		fileNum = append(fileNum, num)
		return err
	})
	sort.Ints(fileNum)
	for i := 0; i < len(fileNum); i++ {
		bytes, _ := os.ReadFile(path.Join(folder, id, strconv.Itoa(fileNum[i])+".ts"))
		_, err = writer.Write(bytes)
	}
	if err != nil {
		fmt.Println(err)
		return "合并错误"
	}
	_ = writer.Flush()
	// return mvName
	return "合并成功"
}

// 下载逻辑
func download0(fileUrl, name, folder string) (Res, error) {
	if len(fileUrl) == 0 {
		return Res{Data: "下载url为空", Code: 500}, nil
	}
	if !tool.IsValidURL(fileUrl) {
		return Res{Data: "url非法", Code: 500}, nil
	}
	fileUrl = strings.TrimSpace(fileUrl)
	defer func() {
		if r := recover(); r != nil {
			errStr := fmt.Sprintf("Error: %v", r)
			tool.SetProgress(fileUrl, errStr, 1)
			fmt.Println("Recovered. Error:\n", r)
		}
	}()
	downloader, id, err := dl.NewTask(folder, name, fileUrl)
	if err != nil {
		panic(err)
	}
	go func() {
		if err := downloader.Start(24); err != nil {
			panic(err)
		}
	}()
	return Res{Data: id, Code: 200}, nil
}
